package com.luyuan.crm.promotion.web;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.event.ActionEvent;
import javax.faces.model.ListDataModel;

import org.hibernate.criterion.Order;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.luyuan.crm.product.model.Product;
import com.luyuan.crm.promotion.Promotion;
import com.luyuan.crm.promotion.PromotionLimitedAmount;
import com.luyuan.crm.promotion.PromotionLimitedMemberLevel;
import com.luyuan.crm.promotion.PromotionLimitedPackage;
import com.luyuan.crm.promotion.PromotionModelCash;
import com.luyuan.crm.promotion.PromotionModelCashIntegral;
import com.luyuan.crm.promotion.PromotionModelIntegral;
import com.luyuan.crm.promotion.PromotionModelN4M;
import com.luyuan.crm.promotion.PromotionModelReduction;
import com.luyuan.crm.promotion.PromotionService;
import com.ruijie.foundation.query.Page;
import com.ruijie.foundation.query.criteria.CriteriaTemplate;
import com.ruijie.foundation.query.criteria.RestrictionTemplate;
import com.ruijie.util.StringUtils;
import com.ruijie.web.jsf.action.BaseAction;
import com.ruijie.web.jsf.context.TableContext;
import com.ruijie.web.jsf.model.PageDataModel;
import com.ruijie.web.jsf.model.TableOrder;
import com.ruijie.web.jsf.model.TablePage;

@Component("promotionAction")
@Scope("view")
public class PromotionAction extends BaseAction implements InitializingBean {
    @Resource(name = "promotionService")
    private PromotionService promotionService;

    private Promotion criteria = new Promotion();

    private Promotion model;

    private PromotionModel promotionModel;

    private PromotionLimited promotionLimited;

    private List<Product> products;

    @Override
    public void afterPropertiesSet() throws Exception {
        String uuid = getRequestParameter("uuid");
        if (StringUtils.isNotEmpty(uuid)) {
            model = promotionService.getPromotionById(uuid);
        }
        else {
            model = new Promotion();
            model.setProducts(new HashSet<Product>());
            model.setModel(new PromotionModelCash());
            model.getModel().setPromotion(model);
            model.setLimited(new PromotionLimitedAmount());
            model.getLimited().setPromotion(model);
        }
        products = new ArrayList<Product>(model.getProducts());
        promotionModel = new PromotionModel();
        promotionLimited = new PromotionLimited();

        if (model.getModel() instanceof PromotionModelCash) {
            promotionModel.setDiscount(((PromotionModelCash) model.getModel()).getDiscount());
            promotionModel.setModel("cash");
        }
        else if (model.getModel() instanceof PromotionModelIntegral) {
            promotionModel.setIntegralTimes(((PromotionModelIntegral) model.getModel()).getIntegralTimes());
            promotionModel.setModel("integral");
        }
        else if (model.getModel() instanceof PromotionModelCashIntegral) {
            promotionModel.setDiscount(((PromotionModelCashIntegral) model.getModel()).getDiscount());
            promotionModel.setIntegralTimes(((PromotionModelCashIntegral) model.getModel()).getIntegralTimes());
            promotionModel.setModel("cash_integral");
        }
        else if (model.getModel() instanceof PromotionModelN4M) {
            promotionModel.setM(((PromotionModelN4M) model.getModel()).getM());
            promotionModel.setN(((PromotionModelN4M) model.getModel()).getN());
            promotionModel.setModel("n4m");
        }
        else if (model.getModel() instanceof PromotionModelReduction) {
            promotionModel.setL(((PromotionModelReduction) model.getModel()).getM());
            promotionModel.setD(((PromotionModelReduction) model.getModel()).getN());
            promotionModel.setModel("reduction");
        }

        if (model.getLimited() instanceof PromotionLimitedMemberLevel) {
            promotionLimited.setMemberLevel(((PromotionLimitedMemberLevel) model.getLimited()).getMemberLevel());
            promotionLimited.setLimited("memberLevel");
        }
        else if (model.getLimited() instanceof PromotionLimitedAmount) {
            promotionLimited.setAmount(((PromotionLimitedAmount) model.getLimited()).getAmount());
            promotionLimited.setLimited("amount");
        }
        else if (model.getLimited() instanceof PromotionLimitedPackage) {
            promotionLimited.setPackingNumber(((PromotionLimitedPackage) model.getLimited()).getPackingNumber());
            promotionLimited.setLimited("package");
        }
    }

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public PromotionLimited getPromotionLimited() {
        return promotionLimited;
    }

    public void setPromotionLimited(PromotionLimited promotionLimited) {
        this.promotionLimited = promotionLimited;
    }

    public PromotionModel getPromotionModel() {
        return promotionModel;
    }

    public void setPromotionModel(PromotionModel promotionModel) {
        this.promotionModel = promotionModel;
    }

    public Promotion getModel() {
        return model;
    }

    public Promotion getCriteria() {
        return criteria;
    }

    public void updatePromotion(ActionEvent event) {
        loadModel();
        List<Product> r = new ArrayList<Product>();
        for (Product product : model.getProducts()) {
            if (!products.contains(product)) {
                r.add(product);
            }
        }
        model.getProducts().removeAll(r);
        model.getProducts().addAll(products);
        promotionService.updatePromotion(model);

        addGlobalI18nMessage("修改成功！");
    }

    public void addPromotion(ActionEvent event) {
        loadModel();
        model.getProducts().addAll(products);
        promotionService.addPromotion(model);

        addGlobalI18nMessage("添加成功！");
    }

    protected void loadModel() {
        if (model.getModel() instanceof PromotionModelCash) {
            ((PromotionModelCash) model.getModel()).setDiscount(promotionModel.getDiscount());
        }
        else if (model.getModel() instanceof PromotionModelIntegral) {
            ((PromotionModelIntegral) model.getModel()).setIntegralTimes(promotionModel.getIntegralTimes());
        }
        else if (model.getModel() instanceof PromotionModelCashIntegral) {
            ((PromotionModelCashIntegral) model.getModel()).setDiscount(promotionModel.getDiscount());
            ((PromotionModelCashIntegral) model.getModel()).setIntegralTimes(promotionModel.getIntegralTimes());
        }
        else if (model.getModel() instanceof PromotionModelN4M) {
            ((PromotionModelN4M) model.getModel()).setM(promotionModel.getM());
            ((PromotionModelN4M) model.getModel()).setN(promotionModel.getN());
        }
        else if (model.getModel() instanceof PromotionModelReduction) {
            ((PromotionModelReduction) model.getModel()).setM(promotionModel.getL());
            ((PromotionModelReduction) model.getModel()).setN(promotionModel.getD());
        }

        if (model.getLimited() instanceof PromotionLimitedMemberLevel) {
            ((PromotionLimitedMemberLevel) model.getLimited()).setMemberLevel(promotionLimited.getMemberLevel());
        }
        else if (model.getLimited() instanceof PromotionLimitedAmount) {
            ((PromotionLimitedAmount) model.getLimited()).setAmount(promotionLimited.getAmount());
        }
        else if (model.getLimited() instanceof PromotionLimitedPackage) {
            ((PromotionLimitedPackage) model.getLimited()).setPackingNumber(promotionLimited.getPackingNumber());
        }
    }

    public void removePromotion(String id) {
        promotionService.deletePromotion(id);

        addGlobalI18nMessage("删除成功！");
    }

    public void onPromotionModelChange(ActionEvent event) {
        String m = getRequestParameter("promotionForm:model");
        if (m.equals("cash")) {
            model.setModel(new PromotionModelCash());
        }
        else if (m.equals("integral")) {
            model.setModel(new PromotionModelIntegral());
        }
        else if (m.equals("cash_integral")) {
            model.setModel(new PromotionModelCashIntegral());
        }
        else if (m.equals("n4m")) {
            model.setModel(new PromotionModelN4M());
        }
        else if (m.equals("reduction")) {
            model.setModel(new PromotionModelReduction());
        }
        model.getModel().setPromotion(model);
    }

    public void onPromotionLimitedChange(ActionEvent event) {
        String l = getRequestParameter("promotionForm:limited");
        if (l.equals("amount")) {
            model.setLimited(new PromotionLimitedAmount());
        }
        else if (l.equals("package")) {
            model.setLimited(new PromotionLimitedPackage());
        }
        else if (l.equals("memberLevel")) {
            model.setLimited(new PromotionLimitedMemberLevel());
        }
        model.getLimited().setPromotion(model);
    }

    public ListDataModel getTableModel() {
        TablePage limit = TableContext.getTablePage();
        List<TableOrder> tableOrders = TableContext.getTableOrders();
        List<Order> orders = new ArrayList<Order>();
        for (TableOrder tableOrder : tableOrders) {
            Order order = tableOrder.toOrder();
            if (order != null) {
                orders.add(order);
            }
        }
        if (orders.isEmpty()) {
            orders.add(Order.desc("endDate"));
        }

        CriteriaTemplate c = CriteriaTemplate.forClass(Promotion.class);
        RestrictionTemplate r = new RestrictionTemplate(true);
        c.add(r.like("theme", criteria.getTheme()));
        if (criteria.getStartDate() != null) {
            // 当天举行的活动
            c.add(r.ge("startDate", criteria.getStartDate()));
            c.add(r.le("endDate", criteria.getStartDate()));
        }
        Page page = promotionService.pagedQuery(c, limit.getPage(), limit.getPageSize(), orders);
        return new PageDataModel(page);
    }
}
